package com.tsysstems.clientEmployee;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tsystems.common.CommonKeys;
import com.tsystems.entities.Employee;
import com.tsystems.entities.Passenger;
import com.tsystems.entities.Station;
import com.tsystems.entities.TimeTableElement;
import com.tsystems.entities.Train;


public class ClientEmployee{

	private final Logger logger = LoggerFactory.getLogger(getClass());
	
	private static ClientEmployee instance;

	private String login;
	
	private static final String host = "localhost";
	private static final int port = 9090;
	private ClientConnectionManager connectionService;
	
	public synchronized static ClientEmployee getInstance() {
		if (instance == null) {			
			instance = new ClientEmployee();
		}
		return instance;
	}
	
	
	public boolean init() {	
		try {
			logger.info("init");
			connectionService = ClientConnectionManager.getInstance();
			connectionService.connect(host, port);		
			return true;
		} catch (UnknownHostException e) {
			logger.error("UnknownHostException", e);
			ClientConnectionManager.getInstance().closeConnection();			
		} catch (IOException e) {
			logger.error("IOException", e);
			ClientConnectionManager.getInstance().closeConnection();
		}
		
		return false;
	}

	
	
	public synchronized String login(String login, String password) {
		try {
			logger.info("LOGIN EMPLOYEE: login = {}, pasword = {}", login, password);
			connectionService.getOutput().writeObject(CommonKeys.LOGIN_EMPL);
			connectionService.getOutput().writeObject(login);
			connectionService.getOutput().writeObject(password);
	
			String result = (String)connectionService.getInput().readObject();
			
			if (result.equals("Вход в систему успешно выполнен")) {
				logger.info("login success");
				this.login = login;

			} else {
				logger.info("login fail");
			}
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}

		return null;
	}
	
	public synchronized String register(Employee employee) {
		try {
			logger.info("REGISTER EMPLOYEE");		
			connectionService.getOutput().writeObject(CommonKeys.REGISTER_EMPL);
			connectionService.getOutput().writeObject(employee);
			String result = (String)connectionService.getInput().readObject();
			logger.info(result);
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	public synchronized String addStation(Station station) {
		try {
			logger.info("ADD STATION");		
			connectionService.getOutput().writeObject(CommonKeys.ADD_STATION);
			connectionService.getOutput().writeObject(station);
			String result = (String) connectionService.getInput().readObject();
			
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
			
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	public synchronized String addTTE(TimeTableElement timeTableElement) {
		try {
			logger.info("ADD TTE");		
			connectionService.getOutput().writeObject(CommonKeys.ADD_TTE);
			connectionService.getOutput().writeObject(timeTableElement);
			String result = (String) connectionService.getInput().readObject();
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
			
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	public synchronized String addPassenger(Passenger passenger) {
		try {
			logger.info("ADD_PASSENGER");		
			connectionService.getOutput().writeObject(CommonKeys.ADD_PASSENGER);
			connectionService.getOutput().writeObject(passenger);
			String result = (String)connectionService.getInput().readObject();
			
			
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	public synchronized String removePassenger(Passenger passenger) {
		try {
			logger.info("REMOVE_PASSENGER");		
			connectionService.getOutput().writeObject(CommonKeys.REMOVE_PASSENGER);
			connectionService.getOutput().writeObject(passenger);
			String result = (String) connectionService.getInput().readObject();
			
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	public synchronized String editPassenger(Passenger passenger) {
		try {
			logger.info("EDIT_PASSENGER");		
			connectionService.getOutput().writeObject(CommonKeys.EDIT_PASSENGER);
			connectionService.getOutput().writeObject(passenger);
			String result = (String) connectionService.getInput().readObject();
			
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public synchronized List<Passenger>  viewPassengersBase() {
		try {
			logger.info("VIEW_PASSENGERS_BASE");		
			connectionService.getOutput().writeObject(CommonKeys.VIEW_PASSENGERS_BASE);
			
			Object object =connectionService.getInput().readObject();
			List<Passenger> result = (List<Passenger>) object;
				
			
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		return null;
		
	}
	
	@SuppressWarnings("unchecked")
	public synchronized List<Train>  viewTrains() {
		try {
			logger.info("VIEW_TRAINS");		
			connectionService.getOutput().writeObject(CommonKeys.VIEW_TRAINS);
			
			Object object =connectionService.getInput().readObject();
			List<Train> result = (List<Train>) object;
						
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		return null;
		
	}
	
	
	@SuppressWarnings("unchecked")
	public synchronized List<Station>  viewStations() {
		try {
			logger.info("VIEW_STATIONS");		
			connectionService.getOutput().writeObject(CommonKeys.VIEW_STATIONS);
			
			Object object =connectionService.getInput().readObject();
			List<Station> result = (List<Station>) object;
						
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		return null;
		
	}
	
	
	@SuppressWarnings("unchecked")
	public synchronized List<TimeTableElement>  viewTimeTableElements() {
		try {
			logger.info("VIEW_TTE");		
			connectionService.getOutput().writeObject(CommonKeys.VIEW_TTE);
			
			Object object =connectionService.getInput().readObject();
			List<TimeTableElement> result = (List<TimeTableElement>) object;
						
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		return Collections.emptyList();
		
	}
	 
	@SuppressWarnings("unchecked")
	public synchronized List<Passenger>  viewPassengersOnTrain(TimeTableElement timeTableElement) {
		try {
			logger.info("VIEW_PASSANGERS_ON_TRAIN");		
			connectionService.getOutput().writeObject(CommonKeys.VIEW_PASSANGERS_ON_TRAIN);
			connectionService.getOutput().writeObject(timeTableElement);
			
			Object object =connectionService.getInput().readObject();
			List<Passenger> result = (List<Passenger>) object;
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		return null;
		
	}
	
	
	
	public synchronized String addTrain(Train train) {
		try {
			logger.info("ADD_TRAIN");		
			connectionService.getOutput().writeObject(CommonKeys.ADD_TRAIN);
			connectionService.getOutput().writeObject(train);
			String result = (String) connectionService.getInput().readObject();
			
			logger.info(result);
			
			return result;
		} catch (IOException e) {
			logger.error("IOException", e);
		} catch (ClassNotFoundException e) {
			logger.error("ClassNotFoundException", e);
		}
		
		return null;
	}

	public String getLogin() {
		return login;
	}
	
	public synchronized void close() {
		try {
			connectionService.getOutput().writeObject(CommonKeys.CLOSE);
		} catch (IOException e) {
			logger.error("IOException", e);
		}
		connectionService.closeConnection();
	}
}
